﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml.Linq;

namespace NoteBox
{
    public delegate void dInt(int id);
    public delegate void dRem(int id,bool repeat,int countRemind, string typeRemind);
    public delegate void dTime(int id, DateTime date, int hour, int minute);
    //public delegate void dView(bool Tasks,bool Mails, bool Notifications);

    public partial class Form1 : Form
    {
        public static string TasksFileName;
        public static string MailProfilesFileName;

        public static double formOpacity1 = 0.55;
        public static double formOpacity2 = 0.9;
        //
        public const int hideTaskHeight = 20;

        List<mTask> mTaskList = new List<mTask>();
        //
        public static MailForm formMail = new MailForm();

        public Form1()
        {
            InitializeComponent();
            Height -= 105;
            TasksFileName = Application.UserAppDataPath + "\\Tasks.xml";
            MailProfilesFileName = Application.UserAppDataPath + "\\MailProfiles.xml";
            if (!ReadTasksFromFile())
            {
                AddNewTask("Заголовок", "Введите задание", 105);
            }
        }
        
        #region moveForm //////////////   Обработка перемещений формы     
        bool formMoved = false;
        int XPos = 0;
        int YPos = 0;

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            XPos = e.X;
            YPos = e.Y;
            formMoved = true;
            this.BringToFront();
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            int maxleft = Screen.PrimaryScreen.WorkingArea.Width-Width;
            int maxtop = Screen.PrimaryScreen.WorkingArea.Height-Height;
            int maxh0 = Screen.PrimaryScreen.WorkingArea.Top;
            int maxl0 = Screen.PrimaryScreen.WorkingArea.Left;
            if (formMoved)
            {
                formMoved = false;
                if (Left > maxleft)
                    Left = maxleft;
                if (Left < maxl0)
                    Left = maxl0;
                if (Top > maxtop)
                    Top = maxtop;
                if (Top < maxh0)
                    Top = maxh0;
            }
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (formMoved)
            {
                Top += e.Y - this.YPos;
                Left += e.X - this.XPos;
            }
        }
        #endregion

        #region Кнопки: добавление события, Настройки, Информация                  + AddNewTask(title,text,h..)
        private void buttonAddNew_Click(object sender, EventArgs e)
        {
            if (Top + Height + 105 > Screen.PrimaryScreen.WorkingArea.Height)
            {
                if (Top - 105 > Screen.PrimaryScreen.WorkingArea.Top)
                {
                    Top -= 105;
                }
                else return;
            }
            AddNewTask("", "", 105);
            TaskChanged = true;
        }

        void AddNewTask(string _title, string _text, int _height)
        {
            mTaskList.Add(new mTask(mTaskList.Count, string.Format("mpanel{0}", mTaskList.Count), Height - 1));
            Height += _height;
            mTaskList[mTaskList.Count - 1].Height = _height-5;
            mTaskList[mTaskList.Count - 1].textBox1.Text = _title;
            mTaskList[mTaskList.Count - 1].richTextBox1.Text = _text;
            mTaskList[mTaskList.Count - 1].HidePressed += new dInt(Hide);
            mTaskList[mTaskList.Count - 1].ClosePressed += new dInt(Close);
            mTaskList[mTaskList.Count - 1].TaskUpPressed += new dInt(TaskUp);
            mTaskList[mTaskList.Count - 1].TaskDownPressed += new dInt(TaskDown);
            mTaskList[mTaskList.Count - 1].HeightResized +=new dInt(HeightResized); 
            mTaskList[mTaskList.Count - 1].TimePressed += new dInt(Time);
            mTaskList[mTaskList.Count - 1].Parent = this;
            mTaskList[mTaskList.Count - 1].BringToFront();
            mTaskList[mTaskList.Count - 1].textBox1.Focus();
            TaskChanged = true;
        }
        private void buttonSettings_Click(object sender, EventArgs e)
        {
            Settings FormSettings = new Settings(1);
            FormSettings.Show();
            TaskChanged = true;
        }
        private void buttonInfo_Click(object sender, EventArgs e)
        {
            Info FormInfo = new Info();
            FormInfo.Show();
        }
        #endregion

        #region someSettingsInMainForm (ontop) и т.п.// также кнопка в трее

        private void buttonViewMail_Click(object sender, EventArgs e)
        {
            if (formMail.Left == 0 && formMail.Top == 0)
            {
                if (Screen.PrimaryScreen.WorkingArea.Width < formMail.Width + Left + Width)
                {
                    if (Left < formMail.Width)
                    {
                        formMail.Left = 0;
                    }
                    else
                        formMail.Left = Left - formMail.Width;
                }
                else
                {
                    formMail.Left = Left + Width;
                }
                formMail.Top = Top;
            }
            if (!formMail.Visible)
                formMail.Visible = true;
            else
                formMail.Visible = false;
        }
        
        private void buttonOnTop_Click(object sender, EventArgs e)
        {
            if (!TopMost)
            {
                TopMost = true;
                buttonOnTop.BackgroundImage = global::NoteBox.Properties.Resources.ButtonsOnTop2;
            }
            else
            {
                TopMost = false;
                buttonOnTop.BackgroundImage = global::NoteBox.Properties.Resources.ButtonsOnTop;
            }
        }
        private void buttonOpacity_Click(object sender, EventArgs e)
        {
            if (Opacity == formOpacity1)
                Opacity = formOpacity2;
            else
                Opacity = formOpacity1;
        }
        private void buttonhide_Click(object sender, EventArgs e)
        {
            Visible = false;
        }
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
            Visible = true;
            BringToFront();
            TopMost = true;
            TopMost = false;
            
        }
        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            CloseMainForm();
        }
        #endregion

        #region Обработка кнопок из панелей - закрыть, свернуть, переместить, время
        public void Hide(int id)
        {
            // разница между максимальным и минимальным положением
            int mDifference;
            int mStep;
            //  сначала проверяем положение - если развернуто
            if (mTaskList[id].Height != hideTaskHeight)
            {
                mDifference = mTaskList[id].PanelOldHeight - hideTaskHeight;
                mTaskList[id].PanelOldHeight = mTaskList[id].Height;
                mStep = 10; // можно другое число
                for (int jo = 0; jo < (mDifference); jo += mStep)
                {
                    this.Height -= mStep;// -= (mTaskList[id].Height - hideTaskHeight);
                    mTaskList[id].Height -= mStep;// = hideTaskHeight;                    
                }
                for (int i = id + 1; i < mTaskList.Count; i++)
                {
                    mTaskList[i].Top -= mDifference;
                }
                mTaskList[id].Height = hideTaskHeight;
                mTaskList[id].buttonTaskHide.BackgroundImage = global::NoteBox.Properties.Resources.ButtonHide2;
            }
            else
            {
                mDifference = mTaskList[id].PanelOldHeight - hideTaskHeight;
                this.Height += mDifference;
                mTaskList[id].Height += mDifference;
                for (int i = id + 1; i < mTaskList.Count; i++)
                {
                    mTaskList[i].Top += mDifference;
                }
                mTaskList[id].buttonTaskHide.BackgroundImage = global::NoteBox.Properties.Resources.ButtonHide;
            }
            Height = mTaskList[mTaskList.Count - 1].Top + mTaskList[mTaskList.Count - 1].Height + 5;
            TaskChanged = true;
        }
        public void Close(int id)
        {
            // разница между максимальным и минимальным положением
            int mDifference;
            int mStep;
            mDifference = mTaskList[id].Height + 5;
            mStep = 10; // можно другое число
            int thisold = this.Height;
            for (int jo = 0; jo < (mDifference); jo += mStep)
            {
                this.Height -= mStep;// -= (mTaskList[id].Height - hideTaskHeight);
                mTaskList[id].Height -= mStep;// = hideTaskHeight;   
            }
            for (int i = id + 1; i < mTaskList.Count; i++)
            {
                mTaskList[i].Top -= mDifference;
            }
            this.Height = thisold - mDifference;
            mTaskList.RemoveAt(id);
            for (int k = 0; k < mTaskList.Count; k++)
            {
                mTaskList[k].ID = k;
            }
            TaskChanged = true;
        }
        public void TaskDown(int id)
        {
            if (id > mTaskList.Count - 2)
                return;
            string tempTitle = mTaskList[id].textBox1.Text;
            string tempText = mTaskList[id].richTextBox1.Text;
            string tempTime = mTaskList[id].labelTime.Text;
            DateTime tempDate = mTaskList[id].RemindTimeDate;
            int tempHour = mTaskList[id].RemindTimeHour;
            int tempMinute = mTaskList[id].RemindTimeMinute;
            //
            if (mTaskList[id].Height != mTaskList[id + 1].Height)
            {
                if (mTaskList[id + 1].Height == hideTaskHeight)
                {
                    Hide(id);
                    Hide(id + 1);
                }
                else
                {
                    //
                }
            }
            mTaskList[id].textBox1.Text = mTaskList[id + 1].textBox1.Text;
            mTaskList[id].richTextBox1.Text = mTaskList[id + 1].richTextBox1.Text;
            mTaskList[id].labelTime.Text = mTaskList[id + 1].labelTime.Text;
            mTaskList[id].RemindTimeDate = mTaskList[id + 1].RemindTimeDate;
            mTaskList[id].RemindTimeMinute = mTaskList[id + 1].RemindTimeMinute;
            mTaskList[id].RemindTimeHour = mTaskList[id + 1].RemindTimeHour;
            //
            mTaskList[id + 1].textBox1.Text = tempTitle;
            mTaskList[id + 1].richTextBox1.Text = tempText;
            mTaskList[id + 1].labelTime.Text = tempTime;
            mTaskList[id + 1].RemindTimeDate = tempDate;
            mTaskList[id + 1].RemindTimeHour = tempHour;
            mTaskList[id + 1].RemindTimeMinute = tempMinute;
            TaskChanged = true;
        }
        public void TaskUp(int id)
        {
            if (id < 1)
                return;
            string tempTitle = mTaskList[id].textBox1.Text;
            string tempText = mTaskList[id].richTextBox1.Text;
            string tempTime = mTaskList[id].labelTime.Text;
            DateTime tempDate = mTaskList[id].RemindTimeDate;
            int tempHour = mTaskList[id].RemindTimeHour;
            int tempMinute = mTaskList[id].RemindTimeMinute;
            if (mTaskList[id].Height != mTaskList[id - 1].Height)
            {
                if (mTaskList[id - 1].Height == hideTaskHeight)
                {
                    Hide(id);
                    Hide(id - 1);
                }
                else
                {
                    //
                }
            }
            //
            mTaskList[id].textBox1.Text = mTaskList[id - 1].textBox1.Text;
            mTaskList[id].richTextBox1.Text = mTaskList[id - 1].richTextBox1.Text;
            mTaskList[id].labelTime.Text = mTaskList[id - 1].labelTime.Text;
            mTaskList[id].RemindTimeDate = mTaskList[id - 1].RemindTimeDate;
            mTaskList[id].RemindTimeMinute = mTaskList[id - 1].RemindTimeMinute;
            mTaskList[id].RemindTimeHour = mTaskList[id - 1].RemindTimeHour;
            //
            mTaskList[id - 1].textBox1.Text = tempTitle;
            mTaskList[id - 1].richTextBox1.Text = tempText;
            mTaskList[id - 1].labelTime.Text = tempTime;
            mTaskList[id - 1].RemindTimeDate = tempDate;
            mTaskList[id - 1].RemindTimeHour = tempHour;
            mTaskList[id - 1].RemindTimeMinute = tempMinute;
            TaskChanged = true;
        }
        public void Time(int id)
        {
            buttonOpacity_Click(new object(), new EventArgs());
            Time FormTime = new Time(id, mTaskList[id].RemindTimeDate, mTaskList[id].RemindTimeHour, mTaskList[id].RemindTimeMinute);
            // Событие таймсет. Возникает при нажатии кнопок ОК/Удалить формы тайм
            FormTime.TimeSet += new dTime(FormTime_TimeSet);
            FormTime.Top = Top;
            FormTime.Left = Left + Width;
            FormTime.ShowDialog();
            // после нажатии кнопки там - управление передается сюда...
            buttonOpacity_Click(new object(), new EventArgs());
            BringToFront();
            Focus();
        }
        void FormTime_TimeSet(int id, DateTime date, int hour, int minute)
        {
            mTaskList[id].RemindTimeDate = date;
            mTaskList[id].RemindTimeHour = hour;
            mTaskList[id].RemindTimeMinute = minute;
            mTaskList[id].SetActive(true);
            //
            if (minute != -1)
                mTaskList[id].RemindTimeCreate();
            else
                mTaskList[id].labelTime.Text = "";
            TaskChanged = true;
        }

        void HeightResized(int id)
        {
            Height = mTaskList[id].lastFormHeight + mTaskList[id].Height;
            for (int i = id; i < mTaskList.Count; i++)
            {
                if (i!=0)
                    mTaskList[i].Top = mTaskList[i - 1].Top + mTaskList[i - 1].Height + 5;
            }

        }
        #endregion

        #region Действия при закрытии
        void CloseMainForm()
        {
            SaveTasksInToFile();
            this.Close();
            
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason.ToString()=="UserClosing")
                if (MessageBox.Show("Уверены, что хотите закрыть NoteBox?", "NoteBox",
                    MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    e.Cancel = true;
                }
        }
        #endregion

        #region Таймер + напоминание - вызов, действия
        // таймер... каждую секунду
        public static bool TaskChanged = false;
        //
        private void timer1_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < mTaskList.Count; i++)
            {
                if (!mTaskList[i].Active)
                    continue;
                if (mTaskList[i].RemindTimeDate.ToShortDateString() == DateTime.Now.ToShortDateString())
                    if ((int)(mTaskList[i].RemindTimeHour) == DateTime.Now.Hour)
                        if ((int)(mTaskList[i].RemindTimeMinute) == DateTime.Now.Minute)
                        {
                            mTaskList[i].SetActive(false);
                            //
                            string lremind = "";
                            lremind = mTaskList[i].RemindTimeHour + " : ";
                            if (mTaskList[i].RemindTimeMinute < 10)
                                lremind += "0";
                            lremind += mTaskList[i].RemindTimeMinute;
                            Reminder FormRem = new Reminder(i, mTaskList[i].textBox1.Text, mTaskList[i].richTextBox1.Text,lremind);
                            // событие - при нажатии ок
                            FormRem.Remind += new dRem(FormRem_Remind);
                            FormRem.Show();

                        }
            }
            if (TaskChanged)
            {
                SaveTasksInToFile();
                TaskChanged = false;
            }
        }
        // событие при нажатии кнопки ок в форме напоминаия
        void FormRem_Remind(int id, bool repeat, int countRemind, string typeRemind)
        {
            if (!repeat)
            {
                return;
            }
            else
            {
                mTaskList[id].SetActive(true);
                switch (typeRemind)
                {
                    case "Минут":
                        mTaskList[id].RemindTimeMinute += countRemind % 60;
                        mTaskList[id].RemindTimeHour += (int)Math.Floor((double)(countRemind / 60));
                        if (mTaskList[id].RemindTimeMinute >= 60)
                        {
                            mTaskList[id].RemindTimeMinute -= 60;
                            mTaskList[id].RemindTimeHour++;
                        }
                        if (mTaskList[id].RemindTimeHour >= 24)
                        {
                            mTaskList[id].RemindTimeHour -= 24;
                            mTaskList[id].RemindTimeDate = mTaskList[id].RemindTimeDate.AddDays(1);
                        }
                        break;
                    case "Часов":
                        mTaskList[id].RemindTimeHour += countRemind % 24;
                        mTaskList[id].RemindTimeDate.AddDays((int)Math.Floor((double)(countRemind / 24)));
                        if (mTaskList[id].RemindTimeHour >= 24)
                        {
                            mTaskList[id].RemindTimeHour -= 24;
                            mTaskList[id].RemindTimeDate = mTaskList[id].RemindTimeDate.AddDays(1);
                        }
                        break;
                    case "Дней":
                        mTaskList[id].RemindTimeDate=mTaskList[id].RemindTimeDate.AddDays(countRemind);
                        break;
                    case "Недель":
                        mTaskList[id].RemindTimeDate = mTaskList[id].RemindTimeDate.AddDays(countRemind * 7);
                        break;
                    case "Месяцев":
                        mTaskList[id].RemindTimeDate = mTaskList[id].RemindTimeDate.AddMonths(countRemind);
                        break;
                    }


                mTaskList[id].RemindTimeCreate();
                TaskChanged = true;
                //mTaskList[id]
            }



        }
        #endregion

        #region Загрузка данных, настроек, сохранение данных

        void SaveTasksInToFile()
        {
            //MessageBox.Show("dgh");
            XDocument XDoc = new XDocument(
                new XDeclaration("1.0", "utf-8", "yes"),
                new XComment("Last edition:" + DateTime.Now.ToString()),
                new XElement("Elements",
                    new XElement ("Tasks"),
                    new XElement ("UserMailProfiles")
                )
            );
            for (int i = 0; i < mTaskList.Count; i++)
            {
                int stdheight; bool minimized;
                if (mTaskList[i].Height==hideTaskHeight)
                {
                    minimized=true;
                    stdheight=mTaskList[i].PanelOldHeight;
                }
                else
                {
                    minimized=false;
                    stdheight=mTaskList[i].Height;
                }
                XElement elem =
                    new XElement("Element",
                        new XAttribute("ID", (i).ToString()),
                        new XAttribute("Active", mTaskList[i].Active.ToString()),
                        new XAttribute("StdHeight", stdheight.ToString()),
                        new XAttribute("Minimized", minimized.ToString()),
                        new XElement("Title", mTaskList[i].textBox1.Text),
                        new XElement("Text", mTaskList[i].richTextBox1.Text),
                        new XElement("LabelTime", mTaskList[i].labelTime.Text),
                        new XElement("Date", mTaskList[i].RemindTimeDate),
                        new XElement("Hour", mTaskList[i].RemindTimeHour),
                        new XElement("Minute", mTaskList[i].RemindTimeMinute),
                        new XElement("Height", mTaskList[i].PanelOldHeight)
                    );
                XDoc.Root.Element("Tasks").Add(elem);
            }
            XElement set =
                new XElement("Settings",
                    new XElement("Opacity", Opacity),
                    new XElement("formOpacity1", formOpacity1),
                    new XElement("formOpacity2", formOpacity2),
                    new XElement("Top",Top),
                    new XElement("Left",Left),
                    new XElement("Visible",Visible),
                    new XElement("TopMost", TopMost),
                    new XElement("MailFormVisible", formMail.Visible),
                    new XElement("MailFormTop", formMail.Top),
                    new XElement("MailFormLeft", formMail.Left),
                    new XElement("activeMail", MailForm.activeMail)
                );
            XDoc.Root.Add(set);

            for (int i = 0; i < MailForm.mails.Count; i++)
            {
                XElement mailprofiles =
                    new XElement("Profile",
                        new XElement("Email", MailForm.mails[i].mMailName),
                        new XElement("Login", MailForm.mails[i].mLogin),
                        new XElement("Password", MailForm.mails[i].mPassword),
                        new XElement("Server", MailForm.mails[i].mServer),
                        new XElement("Port", MailForm.mails[i].mPort),
                        new XElement("Ssl", MailForm.mails[i].mSsl),
                        new XElement("AutoCheck", MailForm.mails[i].mAutoLoad),
                        new XElement("AutoCheckTime", MailForm.mails[i].mAutoLoadTime)
                    );
                XDoc.Root.Element("UserMailProfiles").Add(mailprofiles);
            }
            XDoc.Save(TasksFileName);
        }
        bool ReadTasksFromFile()
        {
            if (!File.Exists(TasksFileName))
                return false;
            
            XDocument XDoc = XDocument.Load(TasksFileName);
            int cnt=0;
            foreach (XElement elem in XDoc.Element("Elements").Element("Tasks").Elements())
            {
                AddNewTask((string)elem.Element("Title"), (string)elem.Element("Text"), (int)elem.Element("Height") + 5);
                //MessageBox.Show(((int)elem.Element("Height")).ToString());
                if ((bool)elem.Attribute("Active"))
                    mTaskList[cnt].SetActive(true);
                else if ((string)elem.Element("LabelTime")!="")
                    mTaskList[cnt].SetActive(false);
                if ((bool)elem.Attribute("Minimized"))
                    Hide(cnt);
                mTaskList[cnt].labelTime.Text = (string)elem.Element("LabelTime");
                mTaskList[cnt].RemindTimeDate = (DateTime)elem.Element("Date");
                mTaskList[cnt].RemindTimeHour = (int)elem.Element("Hour");
                mTaskList[cnt].RemindTimeMinute = (int)elem.Element("Minute");
                cnt++;
            }
            return true;
        }
        // вызов чтения настроек
        private void Form1_Shown(object sender, EventArgs e)
        {
            ReadSettings();
            MailForm.ReadMailProfilesUserFromFile();
        }
        bool ReadSettings()
        {
            if (!File.Exists(TasksFileName))
                return false;
            XDocument XDoc = XDocument.Load(TasksFileName);
            foreach (XElement set in XDoc.Element("Elements").Elements())
            {
                if (set.Name == "Settings")
                {
                    Opacity = (double)set.Element("Opacity");
                    formOpacity1 = (double)set.Element("formOpacity1");
                    formOpacity2 = (double)set.Element("formOpacity2");
                    Top = (int)set.Element("Top");
                    Left = (int)set.Element("Left");
                    Visible = (bool)set.Element("Visible");
                    if ((bool)set.Element("TopMost"))
                        buttonOnTop_Click(new object(), new EventArgs());
                    formMail.Visible = (bool)set.Element("MailFormVisible");
                    formMail.Top = (int)set.Element("MailFormTop");
                    formMail.Left = (int)set.Element("MailFormLeft");
                    MailForm.activeMail = (int)set.Element("activeMail");
                }
            }
            return true;
        }

        #endregion

        #region Изменение кол-ва открытых "ОКОШЕК" // старое - закоментено
        /*
        private void buttonView_Click(object sender, EventArgs e)
        {
            
            ViewSettings formView = new ViewSettings(Left+buttonView.Left, Top+buttonView.Top + buttonView.Height + 1, ViewTasks, formMail.Visible, false);
            formView.ViewSet += new dView(formView_ViewSet);
            formView.Opacity = 0.8;
            formView.ShowDialog();
             */
        // вызывается при нажатии ок (formView)
        /*
        void formView_ViewSet(bool Tasks, bool Mails, bool Notifications)
        {
            ViewTasks = Tasks;
            // Теперь расположение почті...
            if (formMail.Left == 0 && formMail.Top == 0)
            {
                if (Screen.PrimaryScreen.WorkingArea.Width < formMail.Width + Left + Width)
                {
                    if (Left < formMail.Width)
                    {
                        formMail.Left = 0;
                    }
                    else
                        formMail.Left = Left - formMail.Width;
                }
                else
                {
                    formMail.Left = Left + Width;
                }
                formMail.Top = Top;
            }
            formMail.Visible = Mails;
        }*/
        #endregion

    }
}
